import { Injectable } from '@angular/core';
import { APIBase } from 'app/modules/base/api-base';
import { HttpClient } from '@angular/common/http';
import {
  TaskType,
  TaskPeriod,
  TaskTarget,
  TaskService,
} from 'app/modules/task/services/task.service';
import { ToasterService } from 'app/modules/share/services/toaster.service';

@Injectable({
  providedIn: 'root',
})
export class SoftwareService extends APIBase<FormData, SoftwareInfo> {
  constructor(
    private http: HttpClient,
    private taskService: TaskService,
    private toaster: ToasterService,
  ) {
    super(http, '/api/admin/software');
  }

  packages() {
    return new APIBase<any, PackageInfo>(this.http, '/api/admin/software_search');
  }

  softStatus(softID: number) {
    return new APIBase<any, SoftwareStatus>(this.http, `/api/admin/software/${softID}/area`);
  }
  deleteInZone(softID: number, zid: number[]) {
    return this.http.request('DELETE', `${this.baseURL}/${softID}/area`, { body: zid }).toPromise();
  }

  category() {
    return this.http.get('/api/admin/software_category').toPromise();
  }

  upgrade(opt: { zoneIDs?: number[]; computerIDs?: number[]; softwareIDs?: number[] }) {
    const task: UpgradeSoftware = {
      period_type: TaskPeriod.Now,
      type: TaskType.SoftwareUpgrade,
      areas: opt.zoneIDs ? opt.zoneIDs.map(id => ({ id })) : null,
      computers: opt.computerIDs ? opt.computerIDs.map(id => ({ id })) : null,
      content: {
        action: 'install',
        list: opt.softwareIDs ? opt.softwareIDs.map(id => ({ id })) : null,
      },
    };
    if (opt.softwareIDs) {
      if (opt.computerIDs) {
        task.target = TaskTarget.ComputerSoftware;
      } else {
        task.target = opt.zoneIDs ? TaskTarget.ZoneSoftware : TaskTarget.Software;
      }
    } else {
      task.target = opt.zoneIDs ? TaskTarget.Zone : TaskTarget.Computer;
    }
    return this.taskService.create(task);
  }

  updateWithAreaId(areaId: number, t) {
    return this.http.put(this.baseURL + `?area_id=${areaId}`, t).toPromise();  
  }

  resource<W, R>() {
    return new APIBase<W, R>(this.http, 'api/admin/software');
  }
  
}

export interface SoftwareInfo {
  id: number;
  package_name: string;
  size_format: string;
  version: string;
  name: string;
  icon: string;
  source: string;
  website: string;
  remark: string;
  upgrade_at: string;
  mark_at: string;
  updated_at: string;
  category_name?: string;
  architecture?: string;
  area_id: number;
  pk: string;
}
export interface PackageInfo {
  id: number;
  package_name: string;
  version: string;
  architecture: string;
  des: string;
}

export interface SoftwareStatus {
  id: number;
  name: string;
  version: string;
  status: number;
  update_admin_username: string;
  updated_at_time: string;
}

interface UpgradeSoftware {
  period_type: TaskPeriod;
  type?: TaskType;
  target?: TaskTarget;
  areas?: { id: number }[];
  computers?: { id: number }[];
  content?: {
    action: string;
    list?: { id: number }[];
  };
}
